-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
packer_test: make packer test suite modular #13041
Conversation
1454020
to
e7ab35c
Compare
69615d8
to
11815a1
Compare
e7ab35c
to
d86199e
Compare
@@ -1,4 +1,4 @@ | |||
package packer_test | |||
package lib |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to dive into these changes further. But I hesitate to treat this as a separate package. I changed the name to packer_test, as that is the Go idiom for denoting that this is a test package, which does not have direct access to anything in the packer
package and also to ensure that the package is excluded from the final binary.
Previously, the go files ended with _test. go
, which are excluded from the binary. It looks like this refactor changes that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would think the code will not be part of the final binary still, as it's not transitively imported from main.go
, that said if you think that the package name is a problem, we can still move the lib files back to the upper package so that packages using the test suite will still include something called _test
.
3b62757
to
90d99b0
Compare
90d99b0
to
2e91694
Compare
1fcfafa
to
7823d15
Compare
2e91694
to
e24d4f0
Compare
e24d4f0
to
bc8c395
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still working through this but my initial review leaves me with more questions than answers. What would you say is the benefit to the refactor?
@@ -1,8 +1,12 @@ | |||
package packer_test | |||
package core_test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why core_test? What information does it provide that packer_test may not?
type PackerCoreTestSuite struct { | ||
*lib.PackerTestSuite | ||
} | ||
|
||
func Test_PackerPluginSuite(t *testing.T) { | ||
baseSuite, cleanup := lib.PackerCoreSuite(t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the need for PackerCoreTestSuite over lib.PackerTestSuite and how they relate or differ from lib.PackerCoreSuite(). Is this level of abstraction offering a benefit that may not be immediately noticeable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the difference between the two is mostly that the tests run are not the same, being two separate packages/instances of TestSuite means that both can run in parallel. They also may not have the same needs for plugins for example, so one will have to compile a bunch of plugins, and others don't.
As for the names right now, I picked something somewhat randomly, I'm completely open to rename them to something else if you think it's confusing, no problems here!
@@ -1,6 +1,8 @@ | |||
package packer_test | |||
package plugin_tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see now why you chose core_test above. This feels like unneeded package nesting to split the tests. These are all Packer command tests. In fact it appears that this package offers nothing new besides renaming PackerTestSuite to PackerPluginTestSuite. Please let me know if I am missing something?
That said, the tests for plugins should be renamed to better indicate what is being tested. For example TestPackerInitForce
could be renamed to TestPackerInitWithForceFlag
, which read on the screen would be
TestPackerInitWithForceFlag/installs_any_missing_plugins
or TestPackerInitWithForceFlag/reinstalls_plugins_matching_version_constraints
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah I agree, naming could definitely be improved here, as we add more tests we'll need to figure out some naming scheme to make things clearer.
Assert(MustFail(), | ||
Grep("Duplicate local definition"), | ||
Grep("Local variable \"test\" is defined twice")) | ||
Assert(lib.MustFail(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My first question here is what is lib? Why not just MustFail()
. The generic name lib gives no information on the relation of MustFail() to the test suite.
What do you think if we renamed Assert to RunAndAssert
to make it clear that Assert runs the test suite and succeeds if the asserts are true?
RunAndAssert(
MustFail(),
Grep("Duplicate local definition"),
Grep("Local variable \"test\" is defined twice"))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lib
is the common parts, so the base TestSuite that you can extend in other packages, and the gadgets for testing, so all the checkers/pipe infrastructure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can name them common
too if you prefer? I went with lib
because I like the conciseness, but I don't mind renaming this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for renaming Assert
to RunAndAssert
, I agree it's clearer, but it's also longer, I like terse function names :p
But I'm not fundamentally against the renaming tbh
With the proper naming conventions I think we could run tests in using the run filter on go test command. Is dynamic plugin generation an issue or are you concerned that over time things will get slower? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall I'd say the two main benefits are extensibility/separation by theme and ability to run test suits in parallel. There's also some organisation concern here, as one directory to rule them all is not necessarily ideal. That being said, maybe it's premature and we can revisit this later, if/when the organisation of the package becomes a problem.
As for running tests with -run
, yes it is indeed possible; but by default if the test suites are in the same package, they won't run in Parallel I would think. Though maybe it would be feasible with something like t.Parallel
? I'd need to explore that, but then if we keep everything in one big package, I'm worried at some point we'll have a ton of files in one giga directory, which is not necessarily ideal imo.
@@ -1,6 +1,8 @@ | |||
package packer_test | |||
package plugin_tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah I agree, naming could definitely be improved here, as we add more tests we'll need to figure out some naming scheme to make things clearer.
Assert(MustFail(), | ||
Grep("Duplicate local definition"), | ||
Grep("Local variable \"test\" is defined twice")) | ||
Assert(lib.MustFail(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lib
is the common parts, so the base TestSuite that you can extend in other packages, and the gadgets for testing, so all the checkers/pipe infrastructure.
Assert(MustFail(), | ||
Grep("Duplicate local definition"), | ||
Grep("Local variable \"test\" is defined twice")) | ||
Assert(lib.MustFail(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can name them common
too if you prefer? I went with lib
because I like the conciseness, but I don't mind renaming this.
Assert(MustFail(), | ||
Grep("Duplicate local definition"), | ||
Grep("Local variable \"test\" is defined twice")) | ||
Assert(lib.MustFail(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for renaming Assert
to RunAndAssert
, I agree it's clearer, but it's also longer, I like terse function names :p
But I'm not fundamentally against the renaming tbh
type PackerCoreTestSuite struct { | ||
*lib.PackerTestSuite | ||
} | ||
|
||
func Test_PackerPluginSuite(t *testing.T) { | ||
baseSuite, cleanup := lib.PackerCoreSuite(t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the difference between the two is mostly that the tests run are not the same, being two separate packages/instances of TestSuite means that both can run in parallel. They also may not have the same needs for plugins for example, so one will have to compile a bunch of plugins, and others don't.
As for the names right now, I picked something somewhat randomly, I'm completely open to rename them to something else if you think it's confusing, no problems here!
bc8c395
to
db95a73
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that some of the quick name changes I mentioned haven't been applied yet. However, I think those were mostly minor details since this is additive code. If everything is working well, especially with the new gob refactor, let's go ahead and move forward with it, and we can make adjustments as we continue refining it.
While I don't have specific replacement names at the moment, I wanted to mention that the current names aren't immediately clear to me.
Having only one test suite for the whole of Packer makes it harder to segregate between test types, and makes for a longer runtime as no tests run in parallel by default. This commit splits the packer_test suite into several components in order to make extension easier. First we have `lib`: this package embeds the core for running Packer test suites. This ships facilities to build your own test suite for Packer core, and exposes convenience methods and structures for building plugins, packer core, and use it to run a test suite in a temporary directory. Then we have two separate test suites: one for plugins, and one for core itself, the latter of which does not depend on plugins being compiled at all. This sets the stage for more specialised test suites in the future, each of which can run in parallel on different parts of the code.
The compiledPlugins map used to be a global variable, which can be problematic as we move to independent test suites, since those test suites run in the same process space, the global variable could point to now deleted plugin versions/paths in separate suites, which would make tests fail with random errors. To avoid this, the map is now scoped to the test suite, and a new copy is created lazily if used by the test suite.
In terms of organisation, we keep functions that interact with plugins into its own file, therefore the function that build plugin versions should really be in plugin.go, not in suite.go.
As a small reorganisation attempt, this commit moves some file-system oriented functions from plugin.go into its own file so they are more logically grouped.
When testing a packer build or validate, one common use case is to check which plugins are loaded and used by Packer to run a command. This is generally done through Grep, but repeating the same pattern can be redundant, and if the output changes, all those need to be updated. Therefore, this commit introduces a PluginsUsed gadget, which can be orchestrated to ensure a plugin is used, or not used, allowing to check for multiple plugins at once.
db95a73
to
47ea17b
Compare
I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. |
Having only one test suite for the whole of Packer makes it harder to segregate between test types, and makes for a longer runtime as no tests run in parallel by default.
This commit splits the packer_test suite into several components in order to make extension easier.
First we have
lib
: this package embeds the core for running Packer test suites. This ships facilities to build your own test suite for Packer core, and exposes convenience methods and structures for building plugins, packer core, and use it to run a test suite in a temporary directory.Then we have two separate test suites: one for plugins, and one for core itself, the latter of which does not depend on plugins being compiled at all.
This sets the stage for more specialised test suites in the future, each of which can run in parallel on different parts of the code.